package broadcast

import (
	"encoding/binary"
	"encoding/json"
	"fmt"
	"gomonitor-server/src/config"
	"gomonitor-server/src/db"
	"gomonitor-server/src/dto"
	"gomonitor-server/src/mylog"
	"net"
	"strconv"
)

type Message struct {
	Data string `json:"data"`
}

var nextMessageBuffer []byte

func StartTask(appCfg *config.Config) {

	broadcastPort := appCfg.App.BroadcastPort
	if broadcastPort == 0 {
		broadcastPort = 45624
		mylog.Logger.Info("广播端口没有配置,使用默认端口:" + strconv.Itoa(broadcastPort))
	}

	// 解析广播地址
	broadcastUDPAddr, err := net.ResolveUDPAddr("udp", ":"+strconv.Itoa(broadcastPort))
	if err != nil {
		mylog.Logger.Fatal("Error resolving broadcast address:", err)
	}

	// 创建UDP连接
	conn, err := net.ListenUDP("udp", broadcastUDPAddr)
	if err != nil {
		mylog.Logger.Fatal("Error creating UDP connection:", err)
	}
	go func() {
		// 接收消息
		defer conn.Close()
		for {
			err := receiveMessage(conn, broadcastUDPAddr)
			if err != nil {
				mylog.Logger.Println("Error:", err)
			}
		}
	}()
}

func receiveMessage(conn *net.UDPConn, addr *net.UDPAddr) error {
	buffer := make([]byte, 1024)

	var messageBuffer []byte

	// 首先将搁置的数据（如果有的话）加入到消息缓冲区的开始
	messageBuffer = append([]byte{}, nextMessageBuffer...)

	// 清空 nextMessageBuffer，以便用于下一次消息
	nextMessageBuffer = []byte{}

	// 确保 messageBuffer 至少有 9 字节（消息头部标识和数据长度）
	for len(messageBuffer) < 9 {
		n, _, err := conn.ReadFromUDP(buffer)
		if err != nil {
			return fmt.Errorf("error reading from UDP: %w", err)
		}
		messageBuffer = append(messageBuffer, buffer[:n]...)
	}

	// 检查消息头部标识
	if len(messageBuffer) < 9 || !isValidHeader(messageBuffer[:5]) {
		return fmt.Errorf("invalid message header")
	}

	// 解析数据长度
	dataSize := binary.BigEndian.Uint32(messageBuffer[5:9])
	totalSize := int(dataSize) + 9 + 4

	// 继续读取直到获取完整的消息
	for len(messageBuffer) < totalSize {
		n, _, err := conn.ReadFromUDP(buffer)
		if err != nil {
			return fmt.Errorf("error reading from UDP: %w", err)
		}
		messageBuffer = append(messageBuffer, buffer[:n]...)
	}

	// 获取完整消息并验证校验和
	if len(messageBuffer) >= totalSize {
		// 如果读取的数据超出了预期大小，将多余的部分保存为下一个消息的开始
		nextMessageBuffer := messageBuffer[totalSize:]
		if len(nextMessageBuffer) > 0 {
		}
		messageBuffer = messageBuffer[:totalSize]

		messageContent := messageBuffer[9 : totalSize-4]
		checksumBytes := messageBuffer[totalSize-4 : totalSize]
		calculatedChecksum := calculateChecksum(messageContent)
		receivedChecksum := binary.BigEndian.Uint32(checksumBytes)

		if calculatedChecksum != receivedChecksum {
			return fmt.Errorf("checksum verification failed")
		}

		// 存储库
		var sysInfo dto.SysInfo
		err := json.Unmarshal(messageContent, &sysInfo)
		if err != nil {
			mylog.Logger.Error("转换JSON错误..")
			return nil
		}
		_, err = json.Marshal(sysInfo)
		if err != nil {
			mylog.Logger.Println("Error converting data to JSON:", err)
			return nil
		}
		mylog.Logger.Infoln("来自主机:", addr)
		db.RecordDb(sysInfo)
	}

	return nil
}

func isValidHeader(header []byte) bool {
	return len(header) == 5 && header[0] == 0xFF && header[1] == 0xAA && header[2] == 0xCC && header[3] == 0xEE && header[4] == 0x00
}

// 检查数据包是否满足指定格式
func isValidPacket(packet []byte) bool {
	// 检查开头标识
	if len(packet) < 5 || packet[0] != 0xFF || packet[1] != 0xAA || packet[2] != 0xCC || packet[3] != 0xEE || packet[4] != 0x00 {
		return false
	}

	// 检查数据大小长度
	if len(packet) < 10 {
		return false
	}

	return true
}

// 获取数据大小
func getDataSize(packet []byte) uint32 {
	mylog.Logger.Infoln("长度字节:", packet[5:9])
	return binary.BigEndian.Uint32(packet[5:9])
}

// 计算校验和
func calculateChecksum(data []byte) uint32 {
	var sum uint32
	for _, b := range data {
		sum += uint32(b)
	}
	return sum
}
